package com.dc.wifi.main.utils;

import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.util.Log;

import androidx.lifecycle.MutableLiveData;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ThreadUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.dc.wifi.main.DCApplication;
import com.dc.wifi.main.bean.DeviceDataBean;

import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

public class STM32ControlTool {

    private UsbManager usbManager;
    private UsbDevice device;
    private UsbDeviceConnection connection;
    private UsbInterface usbInterface;
    private UsbEndpoint inEndpoint, outEndpoint;
    private ExecutorService executor;
    AudioPlayerUtil audioPlayerUtil;
    public STM32ControlTool(UsbManager usbManager) {
        this.usbManager = usbManager;
        audioPlayerUtil = new AudioPlayerUtil(DCApplication.getInstance());
    }

    public boolean connectDevice(UsbDevice device) {
        this.device = device;
        if (device != null && usbManager != null) {
            connection = usbManager.openDevice(device);
            if (connection != null) {
                usbInterface = device.getInterface(0);
                for (int i = 0; i < usbInterface.getEndpointCount(); i++) {

//                    LogUtils.d("lufeixxx", usbInterface.getInterfaceClass());
//                    if (usbInterface.getInterfaceClass() == 0) { // Assuming class 255 for STM32
//                        outEndpoint = usbInterface.getEndpoint(0);
//                        inEndpoint = usbInterface.getEndpoint(1);
//                        return true;
//                    }

                    UsbEndpoint endpoint = usbInterface.getEndpoint(i);
                    if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                        if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
                            outEndpoint = endpoint;
                        }
                        if (endpoint.getDirection() == UsbConstants.USB_DIR_IN) {
                            inEndpoint = endpoint;
                        }

                    }


                }
            }
        }
        return true;
    }

    public void disconnectDevice() {
        if (connection != null) {
            performAction("stop_capture");
            connection.releaseInterface(usbInterface);
            connection.close();
        }
    }

    public int sendCommand(byte command) {
//        UsbRequest usbRequest = new UsbRequest();
//        usbRequest.initialize(connection, inEndpoint);
//        usbRequest.setClientData("123123");
        if (connection != null && outEndpoint != null) {
            byte[] buffer = new byte[]{command};
            return connection.bulkTransfer(outEndpoint, buffer, buffer.length, 0);
        }
        return 0;
    }
    public int sendCommand2( byte[] buffer ) {
//        UsbRequest usbRequest = new UsbRequest();
//        usbRequest.initialize(connection, inEndpoint);
//        usbRequest.setClientData("123123");
        if (connection != null && outEndpoint != null) {
//            byte[] buffer = new byte[]{command};
            return connection.bulkTransfer(outEndpoint, buffer, buffer.length, 0);
        }
        return 0;
    }

    public int sendCommand3( byte[] buffer,int timeout) {
//        UsbRequest usbRequest = new UsbRequest();
//        usbRequest.initialize(connection, inEndpoint);
//        usbRequest.setClientData("123123");
        if (connection != null && outEndpoint != null) {
//            byte[] buffer = new byte[]{command};
            return connection.bulkTransfer(outEndpoint, buffer, buffer.length, 0);
        }
        return 0;
    }

    public byte[] readResponse() {
        byte[] buffer = new byte[64]; // Adjust buffer size as needed
        int length = 0;
        if (connection != null && inEndpoint != null) {
            length = connection.bulkTransfer(inEndpoint, buffer, buffer.length, 0);
        }
        return length > 0 ? java.util.Arrays.copyOf(buffer, length) : null;
    }

    // Example usage of the tool class
    public int performAction(String action) {
        switch (action) {
            case "start_continuous":
                audioPlayerUtil.play(1000);
                return sendCommand((byte) 0x88);
            case "single_capture":
                return sendCommand((byte) 0x77);
            case "stop_capture":
                audioPlayerUtil.stop();
                return sendCommand((byte) 0xaa);
            case "read_phone_number":
                return sendCommand((byte) 0x99);
            case "write_phone_number":
                byte[] buffer = new byte[]{(byte) 0x66,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
                return sendCommand2(buffer);
            case "write_device_code":
                //,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00
                byte[] buffer3 = new byte[]{(byte) 0x33,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
                return sendCommand2(buffer3);
            case "write_device_code_2":
                //20240711641
                //,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00
                byte[] buffer4 = new byte[]{(byte) 0x33,0x02,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
                return sendCommand2(buffer4);
            case "read_device_code":
                return sendCommand((byte) 0x55);
            case "read_permission_flag":
                return sendCommand((byte) 0x44);
            default:
                return 0;
        }
    }
    public int performAction2(String action,byte[] data) {
        switch (action) {
            case "start_continuous":
                audioPlayerUtil.play(1000);
                return sendCommand((byte) 0x88);
            case "single_capture":
                return sendCommand((byte) 0x77);
            case "stop_capture":
                audioPlayerUtil.stop();
                return sendCommand((byte) 0xaa);
            case "read_phone_number":
                return sendCommand((byte) 0x99);
            case "write_phone_number":

                return sendCommand2(data);
            case "write_device_code":
                //,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00,(byte) 0x00
                byte[] buffer3 = new byte[]{(byte) 0x33,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
                return sendCommand2(buffer3);
            case "write_device_code_2":
                return sendCommand2(data);
            case "read_device_code":
                return sendCommand((byte) 0x55);
            case "read_permission_flag":
                return sendCommand((byte) 0x44);
            default:
                return 0;
        }
    }
  private   MutableLiveData<DeviceDataBean> deviceDataBeanMutableLiveData = new MutableLiveData<>();

    public MutableLiveData<DeviceDataBean> getDeviceDataBeanMutableLiveData() {
        return deviceDataBeanMutableLiveData;
    }

    private int count=0;
    public void xxxx() {
        ThreadUtils.executeBySingleAtFixRate(new ThreadUtils.SimpleTask<DeviceDataBean>() {
            @Override
            public DeviceDataBean doInBackground() throws Throwable {
                int inMax = inEndpoint.getMaxPacketSize();
                DeviceDataBean deviceDataBean = null;
                ByteBuffer byteBuffer = ByteBuffer.allocate(inMax);
                UsbRequest usbRequest = new UsbRequest();
                usbRequest.initialize(connection, inEndpoint);
                usbRequest.queue(byteBuffer);
                if (connection.requestWait() == usbRequest) {
                    byte[] retData = byteBuffer.array();
                    deviceDataBean = processReceivedMessages(byteBuffer,retData);
                    deviceDataBeanMutableLiveData.postValue(deviceDataBean);
                    count++;
                    if (deviceDataBean.type==0&&Integer.parseInt(deviceDataBean.data)>1&&count==5){
                        audioPlayerUtil.play(2000-Integer.parseInt(deviceDataBean.data));
                        count=0;
                    }
                    LogUtils.d("xxxxxxxxxxxxx" + Arrays.toString(retData) + "\n" + deviceDataBean);
                    ToastUtils.showShort(deviceDataBean.data);
                }
                return deviceDataBean;
            }

            @Override
            public void onSuccess(DeviceDataBean result) {
//                zzzz();
            }
        }, 1000, TimeUnit.MILLISECONDS);


    }

    public void receiveMessage(final Stm32CommunicationTool.MessageReceivedListener listener) {
        this.executor = Executors.newSingleThreadExecutor();
        executor.execute(new Runnable() {
            @Override
            public void run() {
                byte[] buffer = new byte[64]; // 根据需要调整缓冲区大小
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        int bytesReceived = connection.bulkTransfer(inEndpoint, buffer, buffer.length, 0);
                        if (bytesReceived > 0 && listener != null) {
                            listener.onMessageReceived(buffer, bytesReceived);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });

    }

    /**
     * @param byteBuffer 处理接收到的消息
     */
    private DeviceDataBean processReceivedMessages(ByteBuffer byteBuffer,byte[] retData) {
        StringBuilder builder = new StringBuilder();
        int position = byteBuffer.position();
        for (int i = 0; i < position; i++) {
            builder.append(byteBuffer.get(i));
        }
        int power = retData[0] + (retData[1] << 8);
        LogUtils.d("lufeixxx", builder.toString());
        DeviceDataBean deviceDataBean = new DeviceDataBean(3, builder.toString(),retData);
        if (position == 1) {
            //标志位
            deviceDataBean.type = 3;
        } else if (position == 11) {
            boolean validPhoneNumber = isValidPhoneNumber(builder.toString());
            if (validPhoneNumber) {
                //手机号
                deviceDataBean.type = 1;
            } else {
                //设备编码
                deviceDataBean.type = 2;
            }
        } else {
            //数据位
            deviceDataBean.type = 0;
        }
        return deviceDataBean;
    }

    /**
     * 检查提供的字符串是否是有效的手机号。
     *
     * @param phoneNumber 需要验证的字符串
     * @return 如果是有效的手机号返回true，否则返回false
     */
    public static boolean isValidPhoneNumber(String phoneNumber) {
        // 定义手机号的正则表达式
        String regex = "^(13|14|15|16|17|18|19)\\d{9}$";

        // 使用Pattern编译正则表达式
        Pattern pattern = Pattern.compile(regex);

        // 使用matcher来检查字符串是否匹配正则表达式
        return pattern.matcher(phoneNumber).matches();
    }

    private void zzzz() {
        Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        Ringtone r = RingtoneManager.getRingtone(DCApplication.getInstance(), notification);
        r.play();
    }
}